# -*-coding: utf-8 -*-
"""
作者：TianyiFan
日期：2023-年08-月16日
用途：CG算法主流程函数
"""

import pandas as pd
from CG_Model import *
import common_fuc
import time

def CG_function(base):
    '''
    给定初始的计划，迭代运行CG的主框架
    :param base: RMP问题当中的计划数组，基于初始解更新后的结果，输入model，开始迭代
    :return: 算法的value
    '''
    # step1：创建RMP主问题模型
    model_rmp = RMP()

    # step2：创建PP子问题模型
    model_i = []  # model_i 存放i个模型，已经初始化但未更新约束的
    for i in range(1, params.V + 1):
        pp_i = PP(i)  # 每个模型对象为pp_i
        model_i.append(pp_i)

    # todo step4：迭代求解-RMP-PP
    reduce_cost = []
    time_RMP = []
    time_pp = []
    for p in range(0,params.iter_count-1):
        reduce_cost.append(0)
        time_RMP.append(0)
        time_pp.append(0)

    while True:
        # step4.1：求解主问题模型
        print("\n--------------------当前CG总计划个数 = {0}-------------------------------------".format(params.iter_count))
        time111 = time.time()
        model_rmp.operate_model(base)
        # step4.2：求解子问题模型
        time222 = time.time()
        time_RMP.append(round(time222 - time111, 3))
        negative_rc = 0
        total_reduce_cost = 0
        for pp_model in model_i:
            print("\n现在求解的是： 车辆-{0}  第{1}次迭代的PP_model==========".format(pp_model.vessel_index, params.iter_count))
            pp_model.operate_model(base)
            model_reduce_cost = pp_model.model.ObjVal
            # 只有值为负、列不重复，才更新主问题里的计划池，否则不更新
            if model_reduce_cost < 0:
                same_column = pp_model.tabulist_solution(base)
                if not same_column:
                    negative_rc += 1
                    pp_model.updata_rmp_plan(base)
                    total_reduce_cost += model_reduce_cost
                    params.set_vessel[pp_model.vessel_index]+=1
                    assign_plan = common_fuc.gamma_var_to_list(pp_model.gamma_k)
                    pp_model.repeat_plan.append(assign_plan)
            else:
                print("vessel-{} 当前计划池数量={}".format(pp_model.vessel_index,params.set_vessel[pp_model.vessel_index]))
            # b = input("是否继续？")
        reduce_cost.append(round(total_reduce_cost/3600,2))
        time333 = time.time()
        time_pp.append(round(time333 - time222,3))
        print("第{0}次迭代  所有PP的求解时间={1:.2f}   negative_rc ={2}".format(params.iter_count, time222 - time111, negative_rc))
        print(f"所有vessel的pool情况= {params.set_vessel[1:-1]}")
        # a = input("是否继续？")
        if negative_rc == 0:
            break
        if params.iter_count > params.total_plan - 2:
            break
        params.iter_count += 1  # 计划数+1
        # a = input("是否继续迭代")

    # step3:导出每轮迭代后，每艘船的成本,第一轮迭代有多个计划，reduce_cost 默认为 0
    cost_delta = pd.DataFrame()
    ganma_k_change = pd.DataFrame()
    for i in range(1,params.V+1):
        cost_list = []
        gama_k_list = []
        for p in range(params.iter_count):
            subblock = common_fuc.ganma_num_to_list(base.A_pi_k[i,p])
            gama_k_list.append(subblock)
            cost_list.append(base.Cost_pi[i,p])
        column_name = "vessel_{}_cost".format(i)
        column_name2 = "veesel_{}_K".format(i)
        cost_delta[column_name] = cost_list
        ganma_k_change[column_name2]=gama_k_list
    cost_delta['reduce_cost'] = reduce_cost
    cost_delta['RMP_time'] = time_RMP
    cost_delta['PP_time'] = time_pp
    cost_delta['total_time'] = cost_delta['RMP_time']+cost_delta['PP_time']

    print("CG迭代过程中，cost、reduces cost、solving_time的变化")
    common_fuc.print_pd(cost_delta)
    print("CG迭代过程中，subblock 决策的变化")
    common_fuc.print_pd(ganma_k_change)

    # step4: 求解计划生成完毕后还原0-1 变量的主问题
    model_mp = MP()
    CG_value = model_mp.operate_model(base)
    return CG_value


